package com.endurance.controller;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSON;
import com.endurance.annotation.MyCacheAnnotation;
import com.endurance.mapper.UserMapper;
import com.endurance.pojo.UserEntity;
import com.endurance.utils.JVMCacheUtils;
import com.endurance.utils.MyCache;
import com.endurance.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author: sunlin
 * @Date: 2024-05-04 12:56
 * @Version: 1.0
 * @Description:
 */
@Slf4j
@RestController
public class UserController {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private MyCache myCache;


    /**
     * 使用普通的方式实现一级缓存与二级缓存
     *
     * @param userId
     * @return
     */
    @RequestMapping("/getUser")
    public UserEntity getUser(Integer userId) {

        // 设置redis的key为： 方法名 + 参数类型 + 用户ID
        String key = "getUser-Integer-" + userId;

        // 从二级缓存中获取数据
        UserEntity redisUser = JSONObject.parseObject(redisUtils.get(key), UserEntity.class);
        if (redisUser != null) {
            return redisUser;
        }

        // 从一级缓存中获取数据
        UserEntity JVMCacheUser = JVMCacheUtils.getEntity(key, UserEntity.class);

        if (JVMCacheUser != null) {
            redisUtils.set(key, JSON.toJSONString(JVMCacheUser));
            return JVMCacheUser;
        }


        // 查询数据库
        UserEntity dataBaseUser = userMapper.getUser(userId);
        if (dataBaseUser == null) {
            return null;
        }
        log.info("返回数据库中的数据：{}", JSON.toJSONString(dataBaseUser));

        // 如果数据库中有数据把数据存入到一级缓存
        JVMCacheUtils.putEntity(key, dataBaseUser);
        log.info("一级缓存中的数据：{}", JVMCacheUtils.cacheMap);
        return dataBaseUser;
    }

    /**
     * 使用装饰模式来重构一级缓存与二级缓存
     *
     * @param userId
     * @return
     */
    @RequestMapping("/getUser1")
    @MyCacheAnnotation
    public UserEntity getUser1(Integer userId) {

        return userMapper.getUser(userId);
    }

}
